<template>
  <div class="flex flex-col items-center h-screen bg-white">
    <!-- PDF Page Display -->
    <div class="relative w-full max-w-6xl overflow-y-auto pdf-container" style="height: calc(100vh - 80px);">
      <!-- Loading State -->
      <div v-if="isLoading" class="absolute inset-0 flex items-center justify-center bg-white bg-opacity-80">
        <div class="flex flex-col items-center">
          <LoaderIcon class="w-8 h-8 text-emerald-500 animate-spin" />
          <span class="mt-2 text-sm text-gray-600">加载中...</span>
        </div>
      </div>

      <!-- Error State -->
      <div v-if="error" class="p-4 bg-red-50 text-red-600 rounded-lg">
        <AlertCircleIcon class="w-6 h-6 inline mr-2" />
        {{ error }}
      </div>

      <!-- PDF Canvas -->
      <canvas ref="pdfCanvas" class="w-full"></canvas>
    </div>

    <!-- Page Navigation -->
    <div class="sticky bottom-0 flex items-center justify-center p-4 bg-white border-t w-full">
      <div class="flex items-center gap-4 w-full">
        <button 
          @click="prevPage"
          :disabled="pageNumber <= 1 || isLoading"
          class="w-10 h-10 rounded-full flex items-center justify-center border border-gray-200 hover:bg-gray-50 disabled:opacity-50"
        >
          <ChevronLeftIcon class="w-5 h-5 text-gray-600" />
        </button>

        <div class="flex-1 flex items-center gap-4">
          <input
            type="range"
            :min="1"
            :max="totalPages"
            v-model="sliderValue"
            @input="handleSliderInput"
            @change="handleSliderChange"
            class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-emerald-500"
          />
          
          <div class="flex items-center gap-2 min-w-[80px]">
            <span class="text-emerald-500 font-medium">{{ pageNumber }}</span>
            <span class="text-gray-400">/</span>
            <span class="text-gray-600">{{ totalPages }}</span>
          </div>
        </div>

        <button 
          @click="nextPage"
          :disabled="pageNumber >= totalPages || isLoading"
          class="w-10 h-10 rounded-full flex items-center justify-center border border-gray-200 hover:bg-gray-50 disabled:opacity-50"
        >
          <ChevronRightIcon class="w-5 h-5 text-gray-600" />
        </button>
      </div>
    </div>
    <showMessage ref="showMessageRef" />
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, defineProps, defineEmits } from 'vue'
import { ChevronLeftIcon, ChevronRightIcon, LoaderIcon, AlertCircleIcon } from 'lucide-vue-next'
import pdfjsLib from '@/utils/pdfWorker'
import axiosClient from '@/utils/axios'
import showMessage from '@/components/share/showMessage.vue'
import { useGeneralStore } from '@/stores/general'
import { markRaw } from 'vue'

const props = defineProps({
  docId: {
    type: Number,
    required: true
  }
})

const emit = defineEmits(['pageContentChange'])  // 定义emit事件

// Component state
const pdfCanvas = ref(null)
const pageNumber = ref(1)
const totalPages = ref(0)
const isLoading = ref(true)
const error = ref(null)
const showMessageRef = ref(null)
const generalStore = useGeneralStore()
const materialId = ref(null)


let pdfDocument = null

// 添加滑块相关的状态
const sliderValue = ref(1)

// 定义用户进度相关的状态和方法
const userRecord = ref(null)

// 分块加载相关状态
const BLOCK_SIZE = 5
const currentBlockIndex = ref(0)
const isLoadingBlock = ref(false)

// 已加载页面的缓存
const pageCache = ref({}) 

// 处理滑块拖动时的事件
const handleSliderInput = (event) => {
  sliderValue.value = parseInt(event.target.value)
  pageNumber.value = sliderValue.value
}

// 处理滑块拖动结束时的事件
const handleSliderChange = async () => {
  await renderPage(sliderValue.value)
}

// 加载用户进度
const loadUserProgress = async () => {
  try {
    const response = await axiosClient.get(`/record/${materialId.value}`)
    userRecord.value = response.data
    if (userRecord.value) {
      pageNumber.value = userRecord.value.page_number
      await renderPage(pageNumber.value)
      sliderValue.value = pageNumber.value
    }
  } catch (error) {
    showMessageRef.value.showMessage('无法加载用户进度。', 'BUG');
  }
}

// 更新用户进度
const updateUserProgress = async (pageNum) => {
  try {
    if (userRecord.value) {
      // 更新现有的进度记录
      await axiosClient.post(`/record/update`, {
        id: userRecord.value.id,
        page_number: pageNum
      })
    }
  } catch (error) {
    showMessageRef.value.showMessage('无法更新用户进度。', 'BUG');
  }
}

// Load PDF document
const loadPDF = async () => {
  try {
    isLoading.value = true;
    error.value = null;
    // 如果props.docId为null，则使用generalStore中的material_id
    if (props.docId === null) {
      materialId.value = generalStore.getMaterialId()
    } else {
      materialId.value = props.docId
      generalStore.setMaterialId(props.docId)
    }

    // 获取PDF文档的总页数
    const response = await axiosClient.get(`/materials/${materialId.value}/info`)
    totalPages.value = response.data.total_pages
    
    // 加载第一个块
    await loadPDFBlock(0)

    // 设置初始页码和滑块值
    pageNumber.value = 1
    sliderValue.value = 1

    // 加载用户进度
    await loadUserProgress()
  } catch (err) {
    showMessageRef.value.showMessage('无法加载 PDF 文件。请检查文件是否有效。', 'BUG');
  } finally {
    isLoading.value = false;
  }
};

// 加载PDF块
const loadPDFBlock = async (blockIndex) => {
  if (isLoadingBlock.value) return
  
  isLoadingBlock.value = true
  try {
    const response = await axiosClient.get(`/materials/${materialId.value}/${blockIndex}`, {
      responseType: 'arraybuffer'
    })
    
    const pdfBlock = await pdfjsLib.getDocument({
      data: response.data,
    }).promise
    
    for (let i = 1; i <= pdfBlock.numPages; i++) {
      const globalPageNum = blockIndex * BLOCK_SIZE + i
      if (globalPageNum > totalPages.value) break // 防止最后一页超出总页数
      if (!pageCache.value[globalPageNum]) {
        pageCache.value[globalPageNum] = markRaw(await pdfBlock.getPage(i))
      }
    }
    
    currentBlockIndex.value = blockIndex
  } catch (error) {
    showMessageRef.value.showMessage('无法加载PDF块。', 'BUG')
  } finally {
    isLoadingBlock.value = false
  }
}

// Render specific page
const renderPage = async (pageNum) => {
  try {
    isLoading.value = true
    error.value = null

    if (pageNum < 1 || pageNum > totalPages.value) {
      throw new Error(`无效的页面索引: ${pageNum}`)
    }

    const blockIndex = Math.floor((pageNum - 1) / BLOCK_SIZE)
    
    if (blockIndex !== currentBlockIndex.value) {
      await loadPDFBlock(blockIndex)
    }
    
    const page = pageCache.value[pageNum]
  
    
    // 提取页面文本
    const textContent = await page.getTextContent()
    const pageText = textContent.items.map(item => item.str).join(' ')
    
    // 发射页面内容变化事件
    emit('pageContentChange', pageText)

    const canvas = pdfCanvas.value
    const context = canvas.getContext('2d')

    // 让 PDF 呈现更接近素描风格
    context.filter = 'contrast(2) brightness(1.2) grayscale(100%)';
    context.strokeStyle = 'black';
    context.shadowColor = 'rgba(0, 0, 0, 0.3)';
    context.shadowBlur = 2;
    
    const viewport = page.getViewport({ scale: 1 })
    const containerWidth = canvas.parentElement.clientWidth
    const scale = containerWidth / viewport.width
    const scaledViewport = page.getViewport({ scale })

    canvas.width = scaledViewport.width
    canvas.height = scaledViewport.height

    await page.render({
      canvasContext: context,
      viewport: scaledViewport
    }).promise

    // 更新用户进度
    generalStore.setPageNumber(pageNum)
    await updateUserProgress(pageNum)
    
    await preloadPages(pageNum)
  } catch (err) {
    error.value = `无法渲染第 ${pageNum} 页: ${err.message}`
    console.error('Page rendering error:', err)
  } finally {
    isLoading.value = false
  }
}

// 预加载相邻页面
const preloadPages = async (currentPageNum) => {
  const preloadRange = 2
  
  for (let i = 1; i <= preloadRange; i++) {
    const prevPageNum = currentPageNum - i
    const nextPageNum = currentPageNum + i
    
    if (prevPageNum > 0 && !pageCache.value[prevPageNum]) {
      const blockIndex = Math.floor((prevPageNum - 1) / BLOCK_SIZE)
      await loadPDFBlock(blockIndex)
    }
    
    if (nextPageNum <= totalPages.value && !pageCache.value[nextPageNum]) {
      const blockIndex = Math.floor((nextPageNum - 1) / BLOCK_SIZE)
      await loadPDFBlock(blockIndex)  
    }
  }
}

// Navigation methods
const prevPage = async () => {
  if (pageNumber.value > 1) {
    pageNumber.value--
    await renderPage(pageNumber.value)
  }
}

const nextPage = async () => {
  if (pageNumber.value < totalPages.value) {
    pageNumber.value++
    await renderPage(pageNumber.value)
  }
}

// Lifecycle hooks
onMounted(() => {
  loadPDF()
})

onUnmounted(() => {
  if (pdfDocument !== null) {
    // @ts-ignore: 浏览器特定API
    pdfDocument.destroy()
  }
})
</script>

<style scoped>
.pdf-container {
  background: #dddddd;
}

.pdf-container canvas {
  filter: contrast(0.8) brightness(1.1) grayscale(90%) saturate(2);
  /* filter:invert(100%) brightness(1.2) contrast(1.5) blur(0.5px);  暗黑模式*/
}
/* 1. 主要的 filter 滤镜属性
滤镜属性	作用	可能的取值
contrast(n)	调整对比度，增加或减少色彩差异	1（默认值），>1 增强对比度，<1 降低对比度
brightness(n)	调整亮度，提高或降低整体亮度	1（默认值），>1 变亮，<1 变暗
grayscale(n%)	使图像变为灰度（黑白效果）	0%（默认，全彩色），100%（完全黑白）
blur(px)	添加模糊效果，模拟阴影或焦点偏移	0px（无模糊），>0px 值越大越模糊
saturate(n)	调整饱和度，增强或减少颜色强度	1（默认值），>1 增强颜色，<1 减弱颜色
invert(n%)	反转颜色（适用于夜间模式或电子屏效果）	0%（正常），100%（完全反转）
sepia(n%)	增加棕黄色复古色调	0%（默认），100%（完全复古风）
hue-rotate(deg)	旋转颜色相位（改变色调）	0deg（默认），180deg（完全变色）
drop-shadow(x y blur color)	添加投影，增强立体感	drop-shadow(4px 4px 5px black)
opacity(n%)	调整透明度	100%（默认，完全可见），0%（完全透明） */
</style>